#property copyright ""
#property link      "mingxinhe@gmail.com"

#property indicator_chart_window
#property indicator_buffers 3
       
extern int NumberOfDays = 120;
extern string StartTime    = "03:15"; 
extern string EndTime = "06:00";  
extern double MaximumRange      = 60.0;    
extern int MA.Period = 200;
extern int MA.Method=0;
extern int MA.Shift=0;
extern int MA.Applied.Price = 0;
extern string MA.Method.Desc = "0:MODE_SMA;1:MODE_EMA;2:MODE_SMMA;3:MODE_LWMA";
extern string MA.Applied.Price.Desc = "0:PRICE_CLOSE;1:PRICE_OPEN;2:PRICE_HIGH;3:PRICE_LOW";
extern int    MA.Width = 2; 
extern color  MA.Color     = Red; 
extern int    BoxText_Offset = 10; 
extern color  LongColor         = DarkGreen; 
extern color  ShortColor   = Red;
extern color  NeutralColor     = Chocolate;

double PriceUP, PriceDN;
int digitFactor = 1;

double MABuffer[];
double HighBuffer[], LowBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void init() {
  DeleteObjects();
  PriceUP = 0;
  PriceDN = 0;
      
   if(Bid<10 && Digits==5) { digitFactor=10;}
   if(Bid<10 && Digits==4) { digitFactor= 1;}

   if(Bid>10 && Digits==3) { digitFactor=10;}
   if(Bid>10 && Digits==2) { digitFactor= 1;} 

   SetIndexStyle(0,DRAW_LINE, STYLE_SOLID, MA.Width, MA.Color);
   SetIndexShift(0,MA.Shift);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexStyle(2,DRAW_LINE);
   
   SetIndexDrawBegin(0,MA.Period -1);
//---- indicator buffers mapping
   SetIndexBuffer(0,MABuffer);  
   SetIndexBuffer(1,HighBuffer);
   SetIndexBuffer(2,LowBuffer);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
}

//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
void deinit() {
  DeleteObjects();
  ObjectsDeleteAll(0, OBJ_TEXT);
return(0);
}

//+------------------------------------------------------------------+
//| Remove all Rectangles                                            |
//+------------------------------------------------------------------+
void DeleteObjects() {
    ObjectsDeleteAll(0,OBJ_RECTANGLE);     
 return(0); 
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
void start() 
{      
   if(Bars<=MA.Period) return(0);
   int ExtCountedBars=IndicatorCounted();
//---- check for possible errors
   if (ExtCountedBars<0) return(-1);
//---- last counted bar will be recounted
   if (ExtCountedBars>0) ExtCountedBars--;
   
   for (int m = Bars-ExtCountedBars; m >= 0; m--)
   { 
       MABuffer[m] = iMA(NULL,0,MA.Period,MA.Shift,MA.Method,MA.Applied.Price,m);
   }

   datetime dtTradeDate=TimeCurrent();

   for (int i=0; i<NumberOfDays; i++) 
   {
      datetime dtTimeBegin, dtTimeEnd;
      double   dPriceHigh,  dPriceLow;
      int      iBarBegin,   iBarEnd;
      string sObjName = "BoxHL "  + TimeToStr(dtTradeDate,TIME_DATE);
      string sHighObjName = "BoxHigh "  + TimeToStr(dtTradeDate,TIME_DATE);
      string sLowObjName = "BoxLow "  + TimeToStr(dtTradeDate,TIME_DATE);

      dtTimeBegin = StrToTime(TimeToStr(dtTradeDate, TIME_DATE) + " " + StartTime);
      dtTimeEnd = StrToTime(TimeToStr(dtTradeDate, TIME_DATE) + " " + EndTime);

      iBarBegin = iBarShift(NULL, 0, dtTimeBegin);
      iBarEnd = iBarShift(NULL, 0, dtTimeEnd);
      dPriceHigh = High[Highest(NULL, 0, MODE_HIGH, iBarBegin-iBarEnd+1, iBarEnd)];
      dPriceLow = Low [Lowest (NULL, 0, MODE_LOW , iBarBegin-iBarEnd+1, iBarEnd)];

      ObjectCreate(sObjName, OBJ_RECTANGLE, 0, 0, 0, 0, 0);
      ObjectCreate(sHighObjName, OBJ_TEXT, 0, 0, 0);
      ObjectCreate(sLowObjName, OBJ_TEXT, 0, 0, 0);

      ObjectSet(sObjName, OBJPROP_TIME1 , dtTimeBegin);
      ObjectSet(sObjName, OBJPROP_TIME2 , dtTimeEnd);

      //---- High-Low Rectangle 
      ObjectSet(sObjName, OBJPROP_PRICE1, dPriceHigh);  
      ObjectSet(sObjName, OBJPROP_PRICE2, dPriceLow);
      ObjectSet(sObjName, OBJPROP_STYLE, STYLE_SOLID);      
      ObjectSet(sObjName, OBJPROP_BACK, True);
      
      ObjectSet(sHighObjName, OBJPROP_TIME1 , iTime(NULL, 0, (iBarBegin + iBarEnd)/2));
      ObjectSet(sHighObjName, OBJPROP_PRICE1 , dPriceHigh + BoxText_Offset*Point*digitFactor);
      ObjectSetText(sHighObjName, "H:" + DoubleToStr(dPriceHigh,Digits), 12, "Times New Roman");
      
      ObjectSet(sLowObjName, OBJPROP_TIME1 , iTime(NULL, 0, (iBarBegin + iBarEnd)/2));
      ObjectSet(sLowObjName, OBJPROP_PRICE1 , dPriceLow - BoxText_Offset*Point*digitFactor);  
      ObjectSetText(sLowObjName, "L:" + DoubleToStr(dPriceLow, Digits), 12, "Times New Roman");          

      if (dPriceHigh - dPriceLow > MaximumRange*Point*digitFactor)
      {
          ObjectSet(sObjName, OBJPROP_COLOR, NeutralColor);
          ObjectSet(sHighObjName, OBJPROP_COLOR, NeutralColor);
          ObjectSet(sLowObjName, OBJPROP_COLOR, NeutralColor);
      }
      else
      {
         for(int j = iBarEnd; j <= iBarBegin; j++)
         {
             double MAValue = iMA(NULL,0,MA.Period,MA.Shift,MA.Method,MA.Applied.Price,j);
           
             if (MAValue > dPriceLow && MAValue < dPriceHigh)
             { 
                 ObjectSet(sObjName, OBJPROP_COLOR, NeutralColor);
                 break;
             }             
         }
             
         
             if (j == iBarBegin + 1)
             {
                 if (MAValue >= dPriceHigh)
                 {
                     ObjectSet(sObjName, OBJPROP_COLOR, ShortColor);
                     ObjectSet(sHighObjName, OBJPROP_COLOR, ShortColor);
                     ObjectSet(sLowObjName, OBJPROP_COLOR, ShortColor);
                     if (i == 0 && iBarEnd > 0)  
                     {
                         HighBuffer[0] = dPriceHigh;
                         LowBuffer[0] = dPriceLow;
                     }
                 }
                 if (MAValue <= dPriceLow)
                 {
                     ObjectSet(sObjName, OBJPROP_COLOR, LongColor);
                     ObjectSet(sHighObjName, OBJPROP_COLOR, LongColor);
                     ObjectSet(sLowObjName, OBJPROP_COLOR, LongColor);
                     if (i == 0 && iBarEnd > 0) 
                     {
                         HighBuffer[0] = -dPriceHigh;
                         LowBuffer[0] = -dPriceLow;
                     }
                 } 
                            
             }
        
      }  


      string sObjDesc = StringConcatenate("High: ",dPriceHigh,"  Low: ", dPriceLow);  
      ObjectSetText(sObjName, sObjDesc,10,"Times New Roman",Black);

      dtTradeDate=decrementTradeDate(dtTradeDate);    

      while (TimeDayOfWeek(dtTradeDate) > 5  || TimeDayOfWeek(dtTradeDate) == 0) 
      {
        dtTradeDate = decrementTradeDate(dtTradeDate);
      }
   }
}

//+------------------------------------------------------------------+
//| Decrement Date to draw objects in the past                       |
//+------------------------------------------------------------------+

datetime decrementTradeDate (datetime dtTimeDate) {
   int iTimeYear=TimeYear(dtTimeDate);
   int iTimeMonth=TimeMonth(dtTimeDate);
   int iTimeDay=TimeDay(dtTimeDate);
   int iTimeHour=TimeHour(dtTimeDate);
   int iTimeMinute=TimeMinute(dtTimeDate);

   iTimeDay--;
   if (iTimeDay==0) {
     iTimeMonth--;
     if (iTimeMonth==0) {
       iTimeYear--;
       iTimeMonth=12;
     }
    
     // Thirty days hath September...  
     if (iTimeMonth==4 || iTimeMonth==6 || iTimeMonth==9 || iTimeMonth==11) iTimeDay=30;
     // ...all the rest have thirty-one...
     if (iTimeMonth==1 || iTimeMonth==3 || iTimeMonth==5 || iTimeMonth==7 || iTimeMonth==8 || iTimeMonth==10 || iTimeMonth==12) iTimeDay=31;
     // ...except...
     if (iTimeMonth==2) if (MathMod(iTimeYear, 4)==0) iTimeDay=29; else iTimeDay=28;
   }
  return(StrToTime(iTimeYear + "." + iTimeMonth + "." + iTimeDay + " " + iTimeHour + ":" + iTimeMinute));
}


//+------------------------------------------------------------------+

